home *** CD-ROM | disk | FTP | other *** search
/ Network Support Library / RoseWare - Network Support Library.iso / btrieve / sql_dp.arj / SIMRMI.PAS next >
Pascal/Delphi Source File  |  1993-08-08  |  6KB  |  186 lines

  1.  
  2.  
  3. {Real mode interrupt support for protected mode using the DPMI.
  4.  Originally based on SIMRMI in C from the Microsoft DDK Dept.
  5.  
  6.  
  7. Rex K. Perkins, CIS 70651,1611
  8.  
  9.  
  10. 6th March 1992.
  11. Revised 10th December 1992}
  12.  
  13.  
  14.  
  15. Unit SimRMI;
  16.  
  17. Interface
  18.  
  19. Type
  20.  
  21.          {Real Mode Register record for DPMI services. Variant type to allow
  22.          register reference by 32, 16 or 8 bit names. Fields ending in Low or
  23.          High are used for padding only and are not intended for use. [Anyone
  24.          know a better way?]
  25.  
  26.          This arangement allows the direct reference of the following registers:
  27.          8 bit:  AL, AH, BL, BH, CL,CH, DL, DH
  28.          16 bit: AX, BX, CX, DX, BP, SI, DI, Flags, ES, DS, FS, GS, IP, CS, SP, SS
  29.          32 bit: EAX, EBX, ECX, EDX, EDI, ESI, EBP}
  30.  
  31.       PRealModeRecord=^TRealModeRecord;
  32.       TRealModeRecord=
  33.                       Record
  34.                         Case Byte Of
  35.                           0:     {32 bit registers}
  36.                             (EDI,ESI,EBP,Reserved,EBX,EDX,
  37.                              ECX,EAX:LongInt);
  38.                           1:     {16 bit registers}
  39.                             (DI,DIHigh,SI,SIHigh,
  40.                              BP,BPHigh,ReservedLow,ReservedHigh,
  41.                              BX,BXHigh,DX,DXHigh,
  42.                              CX,CXHigh,AX,AXHigh,
  43.                              Flags,ES,DS,FS,GS,IP,
  44.                              CS,SP,SS:Word);
  45.                           2:     {8 bit registers}
  46.                             (DILowLow,DILowHigh,DIHighLow,DIHighHigh,
  47.                              SILowLow,SILowHigh,SIHighLow,SIHighHigh,
  48.                              BPLowLow,BPLowHigh,BPHighLow,BPHighHigh,
  49.                              ReservedLowLow,ReservedLowHigh,ReservedHighLow,ReservedHighHigh,
  50.                              BL,BH,BXHighLow,BXHighHigh,
  51.                              DL,DH,DXHighLow,DXHighHigh,
  52.                              CL,CH,CXHighLow,CXHighHigh,
  53.                              AL,AH,AXHighLow,AXHighHigh:Byte)
  54.                       End;
  55.  
  56. Const
  57.              {Pass this constant if you don't need to clear all undefined registers.
  58.              Ensures all selector / segment registers are valid}
  59.         DefaultRMR:TRealModeRecord=(
  60.                                      EDI:0;
  61.                                      ESI:0;
  62.                                      EBP:0;
  63.                                      Reserved:0;
  64.                                      EBX:0;
  65.                                      EDX:0;
  66.                                      ECX:0;
  67.                                      EAX:0;
  68.                                      Flags:0;
  69.                                      ES:0;
  70.                                      DS:0;
  71.                                      FS:0;
  72.                                      GS:0;
  73.                                      IP:0;
  74.                                      CS:0;
  75.                                      SP:0;
  76.                                      SS:0);
  77.  
  78.  
  79.  
  80.   Function SimRealModeInt(IntNumber:Byte; RealModeRegisters:PRealModeRecord):Boolean;
  81.  
  82.     {Simulate a call to the spectified real mode interrupt. The registers passed
  83.      to the real mode code are held in RealModeRegisters. This structure contains
  84.      the register content upon termination of the real mode ISR.
  85.      Returns False if there was an error.}
  86.  
  87.   Function CheckISRInstalled(IntVec:Byte):Boolean;
  88.  
  89.     {Check that there is an Interrupt Service Routine installed. Returns true if a non-zero segment
  90.      was found in the specified ISR vector. If returns False, there is not a valid
  91.      address in the interrupt vector so the interrupt should not be called}
  92.  
  93.   Function GetISRAddress(IntVec:Byte):Pointer;
  94.  
  95.     {Returns the REAL MODE ISR address for vector IntVec. Note that this
  96.      pointer is in Segment:Offset format, not Selector:Offset}
  97.  
  98.  
  99. Implementation
  100.  
  101.  
  102.  
  103.  
  104.   Function SimRealModeInt(IntNumber:Byte; RealModeRegisters:PRealModeRecord):Boolean; Assembler;
  105.  
  106.     {Simulate a call to the spectified real mode interrupt. The registers passed
  107.      to the real mode code are held in RealModeRegisters. This structure contains
  108.      the register content upon termination of the real mode ISR.
  109.      Returns False if there was an error.}
  110.  
  111.   ASM
  112.         push di
  113.         push es
  114.  
  115.         mov  bh,00               {For DOSX to reset the int controller and A20 line.  Windows ingores it.}
  116.         mov  bl,IntNumber        {Tell DPMI which interrupt to simulate}
  117.         xor  cx,cx               {0 bytes to copy to real mode stack}
  118.         les  di,RealModeRegisters{Get the real mode structure}
  119.         mov  ax,$0300            {Function 0300h is simulate real mode interrupt}
  120.         int  31h
  121.  
  122.         jc   @Error              {The carry flag was set, so there was an error}
  123.         mov  ax,True         {Return no error}
  124.         jmp  @AllDone
  125.  
  126.       @Error:
  127.         mov  ax,False        {Return false indicating an error}
  128.  
  129.       @AllDone:
  130.         pop  es
  131.         pop  di
  132.   End;
  133.  
  134.  
  135.  
  136.  
  137.   Function CheckISRInstalled(IntVec:Byte):Boolean;
  138.  
  139.     {Check that there is an ISR installed. Returns true if a non-zero segment
  140.      was found in the specified ISR vector. If returns False, there is not a valid
  141.      address in the interrupt vector so the interrupt should not be called}
  142.  
  143.   Var ISRSegment:Word;
  144.  
  145.   Begin
  146.     ASM
  147.       mov     ax,0200h       {DPMI Get Real Mode Interrupt Vector}
  148.       mov     bl,IntVec      {Check for the specified interrupt}
  149.       int     31h            {Call DPMI}
  150.       mov     ISRSegment,cx  {CX holds the ISR segment}
  151.     End;
  152.  
  153.     If ISRSegment<>0 Then {The Int vector is not 0 so there must be an ISR}
  154.       CheckISRInstalled:=True
  155.     Else
  156.       CheckISRInstalled:=False
  157.   End;
  158.  
  159.  
  160.  
  161.   Function GetISRAddress(IntVec:Byte):Pointer;
  162.  
  163.     {Returns the REAL MODE ISR address for vector IntVec. Note that this
  164.      pointer is in Segment:Offset format, not Selector:Offset}
  165.  
  166.   Var ISRSegment,ISROffset:Word;
  167.  
  168.   Begin
  169.     ASM
  170.       mov     ax,0200h       {DPMI Get Real Mode Interrupt Vector}
  171.       mov     bl,IntVec      {Check for the specified interrupt}
  172.       int     31h            {Call DPMI}
  173.       mov     ISRSegment,cx  {CX holds the ISR segment}
  174.       mov     ISROffset,ds   {DX holds the ISR offset}
  175.     End;
  176.  
  177.     GetISRAddress:=PTR(ISRSegment,ISROffset)  {Return the pointer}
  178.   End;
  179.  
  180.  
  181.  
  182.  
  183. Begin
  184. End.
  185.  
  186.